package stark.app.function.net_ping_ip;
import stark.common.basic.utils.BroadcastReceiverUtil;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.TrafficStats;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;

import com.blankj.utilcode.constant.TimeConstants;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.stark.nettool.lib.NetToolBox;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import cz.mallat.uasparser.UserAgentInfo;
import stark.app.R;
import stark.app.databinding.ActivityNetPingIpBinding;
import stark.common.apis.ApiManager;
import stark.common.apis.base.IpAddrBean;
import stark.common.base.IReqRetCallback;
import stark.common.basic.base.BaseActivity;
import stark.common.basic.device.NetUtil;
import stark.common.basic.inf.IRetCallback;
import stark.common.basic.utils.LogUtil;

public class NetPingIpActivity extends BaseActivity<NetPingIpViewModel, ActivityNetPingIpBinding> implements View.OnClickListener {

    private static final String TAG = "NetPingIpActivity";

    boolean mIsStart;
    EditText mEtIp;

    DownloadManager downloadManager;
    DownloadManager.Request request;
    long mTaskId;
    boolean isTesting;
    Random mRandom = new Random();
    long startTime;
    long currentTime;
    long startDownloadSize;
    Handler mHandler = new Handler();


    @Override
    protected int onCreate() {
        return R.layout.activity_net_ping_ip;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        mHandler.removeCallbacks(mRunnable);
    }

    @Override
    protected void initView() {
        mEtIp = mDataBinding.etIp;
        mDataBinding.btnIpQuery.setOnClickListener(this);
        mDataBinding.btnNetTest.setOnClickListener(this);
        mDataBinding.btnPing.setOnClickListener(this);
        mDataBinding.btnRouter.setOnClickListener(this);
        mDataBinding.btnParseDns.setOnClickListener(this);
        mDataBinding.btnLookupIp.setOnClickListener(this);
        mDataBinding.btnPortScan.setOnClickListener(this);
        mDataBinding.btnRoutingInfo.setOnClickListener(this);
        mDataBinding.btnUserAgent.setOnClickListener(this);
        mDataBinding.btnTraceRoute.setOnClickListener(this);
        mDataBinding.btnMtr.setOnClickListener(this);
        mDataBinding.btnBaseConvert.setOnClickListener(this);
        mDataBinding.btnIpCal.setOnClickListener(this);
    }

    @Override
    protected void initData() {
        mDataBinding.setLifecycleOwner(this);


        //获取下载管理器
        downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        BroadcastReceiverUtil.registerReceiver(this, receiver,
                new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

        String ip = NetworkUtils.getIpAddressByWifi();
        if (TextUtils.isEmpty(ip) || ip.equals("0.0.0.0")) {
            ip = NetworkUtils.getIPAddress(true);
        }
        mDataBinding.etLookupIp.setText(ip);

    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btnNetTest) {
            mViewModel.requestNetUrlData(new NetUrlCallback() {
                @Override
                public void result(String url) {
                    if (isTesting || url == null) return;
                    isTesting = true;
                    mHandler.removeCallbacks(mRunnable);
                    startTime = System.currentTimeMillis();
                    startDownloadSize = TrafficStats.getUidTxBytes(getApplicationInfo().uid);
                    mHandler.post(mRunnable);
                    //创建下载任务,downloadUrl就是下载链接
                    request = new DownloadManager.Request(Uri.parse(url));
                    //将下载任务加入下载队列，否则不会进行下载
                    mTaskId = downloadManager.enqueue(request);
                }
            });
        } else if (id == R.id.btnIpQuery) {
            String ipAddress = mEtIp.getText().toString();
            if (ipAddress != null && ipAddress.length() > 0) {
                mViewModel.requestIpData(ipAddress);
            }
        } else if (id == R.id.btnPing) {
            mIsStart = !mIsStart;
            mDataBinding.btnPing.setText(mIsStart ? "停止" : "开始");
            if (mEtIp.getText().toString() == null || mEtIp.getText().toString().equals("")) {
                mEtIp.setText("www.baidu.com");
            }
            if (mIsStart) {
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        String line = null;
                        try {
                            Process pro = Runtime.getRuntime().exec("ping " + mEtIp.getText().toString());
                            BufferedReader buf = new BufferedReader(new InputStreamReader(
                                    pro.getInputStream()));
                            while ((line = buf.readLine()) != null && mIsStart) {
                                Log.e(TAG, "ping1: " + line);
                            }
                            buf.close();
                            Log.e(TAG, "onClick: buf closed");
                        } catch (Exception ex) {
                            Log.e(TAG, "ping2: " + ex.toString());
                        }
                    }
                }.start();
            }
        } else if (id == R.id.btnRouter) {
            if (mEtIp.getText().toString() == null || mEtIp.getText().toString().equals("")) {
                mEtIp.setText("www.baidu.com");
            }
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    String line = null;
                    try {
                        Process pro = Runtime.getRuntime().exec("traceroute --icmp " + mEtIp.getText().toString());
                        BufferedReader buf = new BufferedReader(new InputStreamReader(
                                pro.getInputStream()));
                        while ((line = buf.readLine()) != null && mIsStart) {
                            Log.e(TAG, "traceroute: " + line);
                        }
                        buf.close();
                        Log.e(TAG, "onClick: buf closed");
                    } catch (Exception ex) {
                        Log.e(TAG, "traceroute: " + ex.toString());
                    }
                }
            }.start();
        } else if (id == R.id.btnParseDns) {
            handleClickParseDns();
        } else if (id == R.id.btnLookupIp) {
            handleClickLookupIp();
        } else if (id == R.id.btnPortScan) {
            handleClickPortScan();
        } else if (id == R.id.btnRoutingInfo) {
            handleClickRoutingInfo();
        } else if (id == R.id.btnUserAgent) {
            handleClickUserAgent();
        } else if (id == R.id.btnTraceRoute) {
            TraceActivity.startForTrace(this);
        } else if (id == R.id.btnMtr) {
            TraceActivity.startForMtr(this);
        } else if (id == R.id.btnBaseConvert) {
            startActivity(BaseConvertActivity.class);
        } else if (id == R.id.btnIpCal) {
            startActivity(IpCalDemoActivity.class);
        }
    }

    @Override
    protected NetPingIpViewModel initViewModel() {
        return new ViewModelProvider(this).get(NetPingIpViewModel.class);
    }

    @Override
    protected void showError(Object obj) {

    }


    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            checkDownloadStatus();//检查下载状态
        }
    };

    //检查下载状态
    private void checkDownloadStatus() {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(mTaskId);//筛选下载任务，传入任务ID，可变参数
        Cursor c = downloadManager.query(query);
        if (c.moveToFirst()) {
            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
            switch (status) {
                case DownloadManager.STATUS_RUNNING:
                    Log.e(TAG, ">>>正在下载");
                    break;

                case DownloadManager.STATUS_SUCCESSFUL:
                    Log.e(TAG, ">>>下载完成");
                    break;
                case DownloadManager.STATUS_FAILED:
                    Log.e(TAG, ">>>下载失败");
                    break;
            }
        }
    }

    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            currentTime = System.currentTimeMillis();
            float speedNet = (float) (TrafficStats.getUidTxBytes(getApplicationInfo().uid) - startDownloadSize) * 1000 / 8 / 1024 / (currentTime - startTime);
            LogUtil.e("下载速度：" + (float) Math.round(speedNet * 100) / 100 + "MB/s");
            int randomVal = mRandom.nextInt(11) + 50;//1/3 - 1/4
            speedNet = speedNet * randomVal / 200;
            LogUtil.e("上传速度" + (float) Math.round(speedNet * 100) / 100 + "");

            mHandler.postDelayed(mRunnable, 50);
        }
    };

    private void handleClickParseDns() {
        String domain = mDataBinding.etHost.getText().toString().trim();
        if (TextUtils.isEmpty(domain)) {
            ToastUtils.showShort("请输入待查询域名");
            return;
        }
        NetUtil.getAllHostAddressByName(domain, new IRetCallback<List<String>>() {
            @Override
            public void onResult(List<String> result) {
                StringBuilder builder = new StringBuilder();
                builder.append("执行结果：\n");
                if (result != null && result.size() > 0) {
                    for (String address : result) {
                        builder.append(domain + "/" + address + "\n");
                    }
                } else {
                    builder.append("无");
                }
                mDataBinding.tvResult.setText(builder.toString());
            }
        });
    }

    private void handleClickLookupIp() {
        String ip = mDataBinding.etLookupIp.getText().toString().trim();
        if (TextUtils.isEmpty(ip)) {
            ToastUtils.showShort("请输入要查询的ip");
            return;
        }
        showDialog("查询中...");
        ApiManager.toolKitApi().getIpAddress(this, ip, new IReqRetCallback<IpAddrBean>() {
            @Override
            public void onResult(boolean success, String msg, @Nullable IpAddrBean result) {
                dismissDialog();
                ToastUtils.showShort(msg);
                if (result != null) {
                    StringBuilder builder = new StringBuilder();
                    builder.append("执行结果:\n");
                    builder.append(result.toString());
                    mDataBinding.tvResult.setText(builder.toString());
                }
            }
        });
    }

    private void handleClickPortScan() {
        String domain = mDataBinding.etDomain.getText().toString().trim();
        if (TextUtils.isEmpty(domain)) {
            ToastUtils.showShort("请输入域名或ip地址");
            return;
        }
        String portStr = mDataBinding.etPorts.getText().toString().trim();
        String[] portSubStrs = portStr.split(",");
        if (portSubStrs == null || portSubStrs.length == 0) {
            ToastUtils.showShort("请输入端口号，端口与端口之间用逗号\",\"隔开");
            return;
        }
        List<Integer> portList = new ArrayList<>();
        for (String portSub : portSubStrs) {
            try {
                portList.add(Integer.parseInt(portSub));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        showDialog("处理中...");
        long startTime = System.currentTimeMillis();
        NetUtil.portTest(domain, portList, new IRetCallback<List<Integer>>() {
            @Override
            public void onResult(List<Integer> result) {
                dismissDialog();
                StringBuilder builder = new StringBuilder();
                builder.append("PortScanning IP: " + domain + "\n");
                for (Integer integer : result) {
                    builder.append("Open : " + integer + "\n");
                }
                builder.append("Open Ports : " + result.size() + "\n");
                builder.append("Time Taken : " + (System.currentTimeMillis() - startTime) * 1f / TimeConstants.SEC + " second");

                mDataBinding.tvResult.setText(builder.toString());
            }
        });
    }

    private void handleClickRoutingInfo() {
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if (wifiInfo == null) {
            ToastUtils.showShort("没有连接wifi");
            return;
        }
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        StringBuilder builder = new StringBuilder();
        builder.append("WIFI网络名称：" + wifiInfo.getSSID() + "\n\n");

        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo != null) {
            builder.append("网络连接类型: " + networkInfo.toString() + "\n\n");
        }

        builder.append("所连接WIFI设备的MAC地址：\n" + wifiInfo.getBSSID() + "\n\n");
        builder.append("WIFI是否被隐藏：" + wifiInfo.getHiddenSSID() + "\n\n");
        builder.append("IP地址：" + convertIp(wifiInfo.getIpAddress()) + "\n\n");
        builder.append("连接的速度：" + wifiInfo.getLinkSpeed() + "Mbps\n\n");
        builder.append("网络信号：" + wifiInfo.getRssi() + "\n\n");
        builder.append("客户端状态的信息：" + wifiInfo.getSupplicantState().toString() + "\n\n");

        mDataBinding.tvResult.setText(builder.toString());
    }

    private static String convertIp(int ipValue) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i <= 3; i++) {
            builder.append((ipValue >> i * 8) & 0xFF);
            if (i < 3) {
                builder.append(".");
            }
        }
        return builder.toString();
    }

    private void handleClickUserAgent() {
        String uaInfo = "Mozilla/5.0 (Linux; Android 10; EBG-AN00 Build/HUAWEIEBG-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.93 Mobile Safari/537.36";
        UserAgentInfo userAgentInfo = NetToolBox.getUaInfo(uaInfo);
        StringBuilder builder = new StringBuilder();
        builder.append("操作系统名称:" + userAgentInfo.getOsFamily() + "\n");
        builder.append("操作系统:" + userAgentInfo.getOsName() + "\n");
        builder.append("浏览器名称:" + userAgentInfo.getUaFamily() + "\n");
        builder.append("浏览器版本:" + userAgentInfo.getBrowserVersionInfo() + "\n");
        builder.append("设备类型:" + userAgentInfo.getDeviceType() + "\n");
        builder.append("浏览器:" + userAgentInfo.getUaName() + "\n");
        builder.append("类型:" + userAgentInfo.getType() + "\n");

        mDataBinding.tvResult.setText(builder.toString());

    }

    private void test() {
    }

}